"
My instances add instance-specific behavior to various class-describing objects in the system. This typically includes messages for initializing class variables and instance creation messages particular to a class. There is only one instance of a particular Metaclass, namely the class which is being described. A Metaclass shares the class variables of its instance.
	
[Subtle] In general, the superclass hierarchy for metaclasses parallels that for classes. Thus,
	Integer superclass == Number, and
	Integer class superclass == Number class.
However there is a singularity at Object. Here the class hierarchy terminates, but the metaclass hierarchy must wrap around to Class, since ALL metaclasses are subclasses of Class. Thus,
	Object superclass == nil, and
	Object class superclass == Class.
"
Class {
	#name : 'Metaclass',
	#superclass : 'ClassDescription',
	#instVars : [
		'thisClass'
	],
	#category : 'Kernel-CodeModel-Classes',
	#package : 'Kernel-CodeModel',
	#tag : 'Classes'
}

{ #category : 'instance variables' }
Metaclass >> addInstVarNamed: aString [
	"Add the argument, aString, as one of the receiver's instance variables."
	<reflection: 'Class structural modification - Instance variable modification'>
	| fullString |
	fullString := String streamContents: [:strm |
		self instVarNames do: [:aString2 | strm nextPutAll: aString2; space].
		strm nextPutAll: aString].
	self instanceVariableNames: fullString
]

{ #category : 'class hierarchy' }
Metaclass >> addObsoleteSubclass: aClass [
	"Do nothing."
	<reflection: 'Class structural modification - Hierarchy modification'>
]

{ #category : 'instance variables' }
Metaclass >> addSlot: aClassSlot [

	<reflection: 'Class structural modification - Slot modification'>
	^self instanceSide addClassSlot: aClassSlot
]

{ #category : 'class hierarchy' }
Metaclass >> addSubclass: aClass [
	<reflection: 'Class structural modification - Hierarchy modification'>
	"Do nothing."
]

{ #category : 'compiling' }
Metaclass >> binding [
	"return an association that can be used as the binding
	 To share it between methods, reuse an existing one if possible"
	^self methodDict
		ifEmpty: [LiteralVariable key: nil value: self]
		ifNotEmpty: [:dict | dict anyOne classBinding]
]

{ #category : 'compiling' }
Metaclass >> bindingOf: varName [
	<reflection: 'Class structural inspection - Variable lookup'>
	^self instanceSide classBindingOf: varName
]

{ #category : 'accessing' }
Metaclass >> category [
	^ self instanceSide category
]

{ #category : 'pool variables' }
Metaclass >> classPool [
	"Answer the dictionary of class variables."
	<reflection: 'Class structural inspection - Shared pool inspection'>
	^self instanceSide classPool
]

{ #category : 'accessing - parallel hierarchy' }
Metaclass >> classSide [
	"Return the metaclass of the couple class/metaclass. Useful to avoid explicit test."
	"Point classSide >>> Point class"
	"Point class classSide >>> Point class"
	<reflection: 'Class structural inspection - Class/Metaclass shift'>
	^ self
]

{ #category : 'accessing - instances and variables' }
Metaclass >> classVarNames [
	"Answer the names of the class variables defined in the receiver's instance."
	<reflection: 'Class structural inspection - Class variable inspection'>
	^self instanceSide
		ifNil: [ #() ]
		ifNotNil: [ :class | class classVarNames ]
]

{ #category : 'class variables' }
Metaclass >> classVariables [
	"Answer the class variables defined in the receiver's instance."
	<reflection: 'Class structural inspection - Class variable inspection'>
	^ self instanceSide
		ifNil: [ #() ]
		ifNotNil: [ :class | class classVariables ]
]

{ #category : 'accessing - comment' }
Metaclass >> comment [
    ^ self instanceSide comment
]

{ #category : 'accessing - comment' }
Metaclass >> comment: aStringOrText [
	"Set the receiver's comment to be the argument, aStringOrText."

	self instanceSide comment: aStringOrText
]

{ #category : 'accessing - comment' }
Metaclass >> comment: aStringOrText stamp: aStamp [
	"Set the receiver's comment to be the argument, aStringOrText."

	self instanceSide comment: aStringOrText stamp: aStamp
]

{ #category : 'accessing - comment' }
Metaclass >> commentSourcePointer [
	^ self instanceSide commentSourcePointer
]

{ #category : 'accessing - comment' }
Metaclass >> commentSourcePointer: anObject [
	^ self instanceSide commentSourcePointer: anObject
]

{ #category : 'accessing - comment' }
Metaclass >> commentStamp [

	^ self instanceSide commentStamp
]

{ #category : 'accessing - comment' }
Metaclass >> commentStamp: changeStamp [
	self instanceSide commentStamp: changeStamp
]

{ #category : 'accessing' }
Metaclass >> environment [

	^thisClass environment
]

{ #category : 'fileout' }
Metaclass >> expandedDefinitionStringFor: aPrinter [

	^ aPrinter expandedMetaclassDefinitionString
]

{ #category : 'accessing - parallel hierarchy - deprecated' }
Metaclass >> hasClassSide [
	<reflection: 'Class structural inspection - Class/Metaclass shift'>
	^ false
]

{ #category : 'accessing - instances and variables' }
Metaclass >> hasClassVarNamed: aString [
	<reflection: 'Class structural inspection - Class variable inspection'>
	^self instanceSide
		ifNil: [ false ]
		ifNotNil: [ :class | class hasClassVarNamed: aString ]
]

{ #category : 'accessing - comment' }
Metaclass >> hasComment [
	"Return whether this class truly has a comment other than the default"
	^ self instanceSide hasComment
]

{ #category : 'compiling' }
Metaclass >> innerBindingOf: varName [

	^self instanceSide innerBindingOf: varName
]

{ #category : 'accessing - parallel hierarchy' }
Metaclass >> instanceSide [
	"Return the class of the couple class/metaclass. Useful to avoid explicit test."
	"Point instanceSide >>> Point"
	"Point class instanceSide >>> Point"
	<reflection: 'Class structural inspection - Class/Metaclass shift'>
	^ self soleInstance
]

{ #category : 'testing' }
Metaclass >> isAnonymous [
	<reflection: 'Class structural inspection - Class kind testing'>
	^self soleInstance isAnonymous
]

{ #category : 'testing' }
Metaclass >> isClass [
	<reflection: 'Class structural inspection - Class/Metaclass shift'>
	^ true
]

{ #category : 'testing' }
Metaclass >> isMeta [
	<reflection: 'Class structural inspection - Class kind testing'>
	^ true
]

{ #category : 'class hierarchy' }
Metaclass >> isMetaclassOfClassOrNil [

	^ self instanceSide
		ifNil: [ true ]
		ifNotNil: [ :nonMetaClass | nonMetaClass == Class ]
]

{ #category : 'testing' }
Metaclass >> isObsolete [
	"Return true if the receiver is obsolete"
	<reflection: 'Class structural inspection - Class kind testing'>
	^self soleInstance isNil "Either no thisClass"
		or:[self soleInstance classSide ~~ self "or I am not the class of thisClass"
			or:[self soleInstance isObsolete]] "or my instance is obsolete"
]

{ #category : 'testing' }
Metaclass >> isReferenced [
	"Metaclasses are never directly referenced in code"
	^false
]

{ #category : 'testing' }
Metaclass >> isSelfEvaluating [
	^self isObsolete not
]

{ #category : 'testing' }
Metaclass >> isUsed [
	"Metaclasses are used by default"
	<reflection: 'Class structural inspection - Class kind testing'>
	^ true
]

{ #category : 'accessing' }
Metaclass >> name [

	"Answer a String that is the name of the receiver, either 'Metaclass' or
	the name of the receiver's class followed by ' class'."

	^ thisClass ifNil: [ 'a Metaclass' ] ifNotNil: [ thisClass name , ' class' ]
]

{ #category : 'instance creation' }
Metaclass >> new [
	"The receiver can only have one instance. Create it or complain that
	one already exists."

	thisClass class ~~ self
		ifTrue: [^thisClass := self basicNew]
		ifFalse: [self error: 'A Metaclass should only have one instance!']
]

{ #category : 'instance creation' }
Metaclass >> newAnonymousSubclass [
	<reflection: 'Class structural modification - Anonymous class creation'>
	^self instanceSide newAnonymousSubclass class
]

{ #category : 'class hierarchy' }
Metaclass >> obsoleteSubclasses [
	"Answer the receiver's subclasses."
	<reflection: 'Class structural inspection - Iterating and querying hierarchy'>
	self isMetaclassOfClassOrNil ifTrue: [ ^ #() ].
	^ self instanceSide obsoleteSubclasses collect: [ :aSubclass | aSubclass classSide ]
]

{ #category : 'accessing' }
Metaclass >> package [
	^ self instanceSide package
]

{ #category : 'accessing' }
Metaclass >> packageTag [
	^ self instanceSide packageTag
]

{ #category : 'compiling' }
Metaclass >> possibleVariablesFor: misspelled continuedFrom: oldResults [

	^ self instanceSide possibleVariablesFor: misspelled continuedFrom: oldResults
]

{ #category : 'copying' }
Metaclass >> postCopy [
	"Don't share the reference to the sole instance."

	super postCopy.
	self classLayout: (layout copy host: self).
	thisClass := nil
]

{ #category : 'instance variables' }
Metaclass >> removeSlot: aClassSlot [
	<reflection: 'Class structural modification - Slot modification'>
	^self instanceSide removeClassSlot: aClassSlot
]

{ #category : 'class hierarchy' }
Metaclass >> removeSubclass: aClass [
	<reflection: 'Class structural modification - Hierarchy modification'>
	"Do nothing."
]

{ #category : 'pool variables' }
Metaclass >> sharedPoolNames [
	<reflection: 'Class structural inspection - Shared pool inspection'>
	^#()
]

{ #category : 'initialization' }
Metaclass >> slots: slotCollection [

	| theClass |
	theClass := self instanceSide.

	theClass := theClass classInstaller update: theClass to: [ :builder |
		builder classSlots: slotCollection ].
	^ theClass classSide
]

{ #category : 'accessing' }
Metaclass >> soleInstance [
	"The receiver has only one instance. Answer it."

	^thisClass
]

{ #category : 'compiling' }
Metaclass >> sourceCodeTemplate [
	"Answer an expression to be edited and evaluated in order to define
	methods in this class or trait."

	^ 'methodSelectorAndArgumentNames
	"comment stating purpose of class-side method"
	"scope: class-variables  &  class-instance-variables"

	| temporary variable names |
	statements'
]

{ #category : 'class hierarchy' }
Metaclass >> subclasses [
	"Answer the receiver's subclasses."
	<reflection: 'Class structural inspection - Iterating and querying hierarchy'>
	self isMetaclassOfClassOrNil ifTrue: [ ^ #() ].
	^ self instanceSide subclasses collect: [ :aSubclass | aSubclass classSide ]
]

{ #category : 'class hierarchy' }
Metaclass >> subclassesDo: aBlock [
	"Evaluate aBlock for each of the receiver's immediate subclasses."
	<reflection: 'Class structural inspection - Iterating and querying hierarchy'>
	self isMetaclassOfClassOrNil ifTrue: [ ^ self ].
	self instanceSide subclasses do: [ :each | aBlock value: each classSide ]
]

{ #category : 'copying' }
Metaclass >> veryDeepCopyWith: deepCopier [

	"Return self.  Must be created, not copied.  Do not record me."
]
